#!/usr/bin/env node

require('./utils')
const express = require('express')
const path = require('path')
const https = require('https');
const http = require('http')
const fs = require('fs')
const app = express()
const merge = require('webpack-merge')
const webpack = require('webpack')
const devConfig = require('./dev.config.js')

const argv = process.argv[2]

const file = path.join(devConfig.output.path, './index.html')

const nodeEnv = process.env.NODE_ENV;

app.use('/', express.static(path.join(__dirname, '../../../static')))

if (argv === 'dev') {
    process.env.NODE_ENV = 'development'
    const luban = require('../../../luban.config.js')
    const config = merge(devConfig, luban.pack)
    const compiler = webpack(config)

    compiler.hooks.done.tap('done', function (data) {
        console.log('client_compile_complete');
    });

    const middleware = require('webpack-dev-middleware')

    const middlewareComplier = middleware(compiler, {
        writeToDisk: !!(luban.server && luban.server.writeToDisk),
        stats: {
            colors: true,
            modules: false,
            children: false,
            chunks: false,
            chunkModules: false
        }
    })

    // const proxy = require('express-http-proxy');
    // app.use('/', proxy('https://dev.ketianyun.com', {
    //     filter: (req, res) => {
    //         return (req.url.indexOf('/rest') == 0 ||
    //             req.url.indexOf('/conf') == 0 )
    //     },
    //     proxyReqPathResolver: (req, res) => {
    //         return req.url
    //     }
    // }))

    const proxyConf = luban.server && luban.server.proxy;
    if (proxyConf) {
        const proxy = require('express-http-proxy');
        for (const item of proxyConf) {
            app.use(item.use, proxy(item.proxyUrl, {
                filter: item.filter,
                proxyReqPathResolver: item.proxyReqPathResolver
            }))
        }

    }
    app.use('/', express.static(path.join(__dirname, '../../../public')))
    app.use(middlewareComplier)

    function sendFileFun(res) {
        let html = middlewareComplier.fileSystem.readFileSync(file)
        res.end(html)
    }

    /**
     * express router 会优先匹配最近的路由
     */

    // '/'
    app.get('/', function (req, res) {
        sendFileFun(res)
    })

    // map routes
    luban.server.routes && luban.server.routes.map(item => {
        app.get(item, function (req, res) {
            sendFileFun(res)
        })
    })

    // '*' 通配
    app.get('*', function (req, res) {
        sendFileFun(res)
    })

    const options = {
        key: fs.readFileSync(path.join(__dirname, './secret/server.key')),
        cert: fs.readFileSync(path.join(__dirname, './secret/server.crt'))
    }

    const port = luban.server && luban.server.port || 3000
    https.createServer(options, app).listen(port + 1)
    http.createServer(app).listen(port, () => {
        console.log(`\n\nlisten port:${port} ${port + 1}\n`)
    })
}


if (argv === 'build') {
    process.env.NODE_ENV = 'production'
    const luban = require('../../../luban.config.js')
    const buildConfig = require('./build.config')
    const config = merge(buildConfig, luban.pack)
    const compiler = webpack(config)
    compiler.run((err, stats) => {
        if (!err) {

            console.log('build success!')

            const origin = path.join(__dirname, '../../../public')
            const target = path.join(__dirname, '../../../static')
            const isHasPublic = fs.existsSync(origin)
            if (isHasPublic) {
                copy(origin, target)
            }
            console.log('client_compile_complete');
        }
    })

    //  == copy public
    const copy = (origin, target) => {
        let paths = fs.readdirSync(origin)

        paths.forEach(p => {
            const o = `${origin}/${p}`
            const t = `${target}/${p}`
            fs.stat(o, (err, stats) => {
                if (stats.isFile()) {
                    fs.readFile(o, (err, data) => {
                        fs.writeFileSync(t, data)
                    })
                } else {
                    fs.access(t, (err) => {
                        if (err) {
                            fs.mkdirSync(t, {recursive: true})
                            copy(o, t)
                        }

                    })

                }
            })
        })
    }

}

if (argv === 'server') {
    const luban = require('../../../luban.config.js')
    app.get('/', function (req, res) {
        res.sendFile(file)
    })

    luban.server.routes && luban.server.routes.map(item => {
        app.get(item, function (req, res) {
            res.sendFile(file)
        })
    })
    const options = {
        key: fs.readFileSync(path.join(__dirname, './secret/server.key')),
        cert: fs.readFileSync(path.join(__dirname, './secret/server.crt'))
    }

    const port = luban.server && luban.server.port || 3000
    https.createServer(options, app).listen(port + 1)
    http.createServer(app).listen(port, () => {
        console.log(`\n\nlisten port:${port} ${port + 1}\n`)
    })

}


// 生成服务器端私钥
// $ openssl genrsa -out server.key 1024

//生成服务端公钥
// $ openssl rsa -in server.key -pubout -out server.pem

//生成CA私钥
// $ openssl genrsa -out ca.key 1024

//生成csr文件
// $ openssl req -new -key ca.key -out ca.csr

//生成自签名证书
// $ openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt

//生成server.csr文件
// $ openssl req -new -key server.key -out server.csr

//生成带有ca签名的证书
// $ openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
